/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package jxta;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.jxta.discovery.DiscoveryService;
import net.jxta.document.AdvertisementFactory;
import net.jxta.document.MimeMediaType;
import net.jxta.exception.PeerGroupException;
import net.jxta.id.IDFactory;
import net.jxta.peer.PeerID;
import net.jxta.peergroup.PeerGroupID;
import net.jxta.peergroup.PeerGroup;
import net.jxta.pipe.PipeID;
import net.jxta.pipe.PipeService;
import net.jxta.platform.NetworkManager;
import net.jxta.platform.NetworkManager.ConfigMode;
import net.jxta.protocol.PipeAdvertisement;
import utilidades.ConsultaAdvertisement;
import utilidades.Id;

/**
 *
 * @author kastillo
 */
public class Configuracion {

    /**Network manager de JXTA, clase de la que se obtienen las configuraciones*/
    private NetworkManager manager;
    //Se definene los diferentes id
    private PeerID peerId;
    private PeerGroupID peerGroupId;
    //Valores iniciales
    private ConfigMode configMode;
    private String nombreInstancia;
    private String nombreGrupo;
    private String nombrePeer;
    private DiscoveryService discovery;
    private PeerGroup netPeerGroup;
    private PipeService pipeService;
    private PipeAdvertisement pipeAdv;
    private PipeAdvertisement pipeDescarga = null;
    private PipeAdvertisement pipeTokenEM = null;
    private PipeAdvertisement pipeSubidaEM = null;

    Configuracion(ConfigMode configMode, String nombreInstancia, String nombrePeer) {
        this.configMode = configMode;
        this.nombreInstancia = nombreInstancia;
        this.nombrePeer = nombrePeer;

    }

    /**
     * @return the manager
     */
    public NetworkManager getManager() {
        return manager;
    }

    /**
     * @return the peerId
     */
    public PeerID getPeerId() {
        return peerId;
    }

    /**
     * @param aPeerId the peerId to set
     */
    public void setPeerId(PeerID aPeerId) {
        peerId = aPeerId;
    }

    /**
     * @return the peerGroupId
     */
    public PeerGroupID getPeerGroupId() {
        return peerGroupId;
    }

    /**
     * @return the configMode
     */
    public ConfigMode getConfigMode() {
        return configMode;
    }

    /**
     * @param aConfigMode the configMode to set
     */
    public void setConfigMode(ConfigMode aConfigMode) {
        configMode = aConfigMode;
    }

    /**
     * @return the nombreInstancia
     */
    public String getNombreInstancia() {
        return nombreInstancia;
    }

    /**
     * @param aNombreInstancia the nombreInstancia to set
     */
    public void setNombreInstancia(String aNombreInstancia) {
        nombreInstancia = aNombreInstancia;
    }

    /**
     * @return the nombreGrupo
     */
    public String getNombreGrupo() {

        return nombreGrupo;
    }

    /**
     * @return the nombrePeer
     */
    public String getNombrePeer() {
        return nombrePeer;
    }

    /**
     * @param aNombrePeer the nombrePeer to set
     */
    public void setNombrePeer(String aNombrePeer) {
        nombrePeer = aNombrePeer;
    }

    /**
     * @return the netPeerGroup
     */
    public PeerGroup getNetPeerGroup() {

        return netPeerGroup;
    }

    public void iniciarJXTA() {
        try {

            manager = new NetworkManager(
                    configMode,
                    nombreInstancia,
                    new File(".cache", nombreInstancia).toURI());
            manager.startNetwork();


            cargarServicios();
            registrarAdvertisementConsulta();


        } catch (PeerGroupException ex) {
            Logger.getLogger(Configuracion.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(Configuracion.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    private void cargarServicios() {
        netPeerGroup = this.manager.getNetPeerGroup();
        pipeService = this.netPeerGroup.getPipeService();
        peerGroupId = this.manager.getInfrastructureID();
        discovery = this.netPeerGroup.getDiscoveryService();
        nombrePeer = this.netPeerGroup.getPeerName();
        peerId = this.manager.getPeerID();

    }

    /**
     * @return the discovery
     */
    public DiscoveryService getDiscovery() {

        return discovery;
    }

    /**
     * @return the PipeService
     */
    public PipeService getPipeService() {

        return pipeService;
    }

    /**
     * @return the discovery
     */
    private void registrarAdvertisementConsulta() {
        AdvertisementFactory.registerAdvertisementInstance(
                ConsultaAdvertisement.getAdvertisementType(),
                new ConsultaAdvertisement.Instantiator());

        System.out.println("SE registro el AdvertisementConsulta");
    }

    public PipeAdvertisement getPipeAdvertisement() {
        try {
            //Creates input pipe
            FileInputStream is = new FileInputStream("saeedPipe.adv");
            pipeAdv = (PipeAdvertisement) AdvertisementFactory.newAdvertisement(MimeMediaType.XMLUTF8, is);
            System.out.println("adv " + pipeAdv);
            is.close();
        } catch (IOException ex) {
            Logger.getLogger(Configuracion.class.getName()).log(Level.SEVERE, null, ex);
        }
        return pipeAdv;
    }

    public PipeID getNewPipeID() {
        return Id.createNewPipeID(getPeerGroupId());
    }

    public PipeAdvertisement getNewPipeAdvertisement() {
        PipeID pipeID = null;


        pipeID = getNewPipeID();

        PipeAdvertisement advertisement = (PipeAdvertisement) AdvertisementFactory.newAdvertisement(PipeAdvertisement.getAdvertisementType());

        advertisement.setPipeID(pipeID);
        advertisement.setType(PipeService.UnicastType);
        advertisement.setName(nombrePeer);
        return advertisement;
    }

    public PipeAdvertisement getGlobalPipeAdvertisement() {
        final String PIPEIDSTR = "urn:jxta:uuid-59616261646162614E50472050325033C0C1DE89719B456691A596B983BA0E1004";
        PipeID pipeID = null;

        try {
            pipeID = (PipeID) IDFactory.fromURI(new URI(PIPEIDSTR));
        } catch (URISyntaxException use) {
            use.printStackTrace();
        }
        PipeAdvertisement advertisement =
                (PipeAdvertisement) AdvertisementFactory.newAdvertisement(PipeAdvertisement.getAdvertisementType());

        advertisement.setPipeID(pipeID);
        advertisement.setType(PipeService.UnicastType);
        advertisement.setName("GlobalPipeAdvertisement");
        return advertisement;

    }


    public PipeAdvertisement getPipeDescarga() {
        if(pipeDescarga == null)
         pipeDescarga = getNewPipeAdvertisement();
        return pipeDescarga;
    }
/**
 * Crea el PipeAdvertque será utilizado para recibir peticiones
 * de la exclusión mutua, concernientes a la gestión del token.
 *
 * @return El PipeAdvertisment
 */
    public PipeAdvertisement getPipeTokenEM(){
        if(pipeTokenEM == null){
            pipeTokenEM = getNewPipeAdvertisement();
        }
        return pipeTokenEM;
    }

    /**
     * Crea el PipeAdvertisment que será utilizado para recibir las peticiones de actualizar
     * un archivo, es decir cuando un archivo se envia para ser modificado por
     * el peer que tiene el token, este peer devuelve el archivo utilizando este pipe.
     *
     * @return PipeAdvertisement
     */
    public PipeAdvertisement getPipeSubidaEM() {
        if(pipeSubidaEM == null){
            pipeSubidaEM = getNewPipeAdvertisement();
        }
        return pipeSubidaEM;
    }
}
